<html>
<head><meta charset="utf-8"><title>Reference in `ptr::write` question · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference.20in.20.60ptr.3A.3Awrite.60.20question.html">Reference in `ptr::write` question</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="220858891"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference%20in%20%60ptr%3A%3Awrite%60%20question/near/220858891" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Kitsu <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference.20in.20.60ptr.3A.3Awrite.60.20question.html#220858891">(Dec 24 2020 at 09:26)</a>:</h4>
<p>I've found quite a strange thing in <code>ptr::write</code> source: <a href="https://doc.rust-lang.org/src/core/ptr/mod.rs.html#875">https://doc.rust-lang.org/src/core/ptr/mod.rs.html#875</a>. In particular, I'm curious about <code>&amp;mut *dst</code> part and how does it handle a pointer to uninitialized memory, so consider the following example:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="n">MaybeUninit</span>::<span class="o">&lt;</span><span class="kt">u8</span><span class="o">&gt;</span>::<span class="n">uninit</span><span class="p">();</span><span class="w"></span>
<span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="p">.</span><span class="n">as_mut_ptr</span><span class="p">().</span><span class="n">write</span><span class="p">(</span><span class="mh">0x12</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>As far as I know, ref must always reference a properly initialized object. And in the <code>ptr::write</code> the pointer for uninitialized memory is dereferenced passing a mutable ref. So the unsafe block should be similar to <code>let y = &amp;mut *x; intrinsics::move_val_init(y, 0x12);</code>. Does it mean that either <code>ptr::write</code> has an undefined behavior (due to <code>y</code> creation is invalid), or it just exploits some internal knowledge regarding rvalue ref behavior?</p>



<a name="220866350"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference%20in%20%60ptr%3A%3Awrite%60%20question/near/220866350" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference.20in.20.60ptr.3A.3Awrite.60.20question.html#220866350">(Dec 24 2020 at 12:19)</a>:</h4>
<p>Two points:</p>
<ul>
<li><code>core::ptr::write</code> does not, conceptually, dereference it's argument. It's merely undefined behaviour if the pointer is not dereferenceable (in particular, it's never been a requirement that the pointer points to an initialized value). In fact, a pattern for initializing a MaybeUninit is to use <code>as_mut_ptr()</code> then write. </li>
<li>Even if it did, &lt;<a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/77">https://github.com/rust-lang/unsafe-code-guidelines/issues/77</a>&gt; implies that references do not need to refer to valid data, and this is only a safety invariant (unrelated safe code may assume that references refer to valid data).</li>
</ul>



<a name="220867931"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference%20in%20%60ptr%3A%3Awrite%60%20question/near/220867931" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Kitsu <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference.20in.20.60ptr.3A.3Awrite.60.20question.html#220867931">(Dec 24 2020 at 12:47)</a>:</h4>
<blockquote>
<p>in particular, it's never been a requirement that the pointer points to an initialized value</p>
</blockquote>
<p>Is there any significant difference between "dereferencable" and "readable" for that context? If no, then e.g. <code>ptr::read</code> doc claims: «<code>src</code> must point to a properly initialized value of type <code>T</code>». And if yes, could you clarify that one?</p>
<blockquote>
<p>references do not need to refer to valid data</p>
</blockquote>
<p>Thus UB is accessing uninitialized memory by reference, but not creation that one, am I correct? That's a little unintuitive for me then. Besides, the issue isn't closed yet and it's quite a big to follow to be honest. Perhaps, maybe there's a summary of what has been resolved/discussed?</p>



<a name="220868536"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference%20in%20%60ptr%3A%3Awrite%60%20question/near/220868536" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference.20in.20.60ptr.3A.3Awrite.60.20question.html#220868536">(Dec 24 2020 at 13:01)</a>:</h4>
<p><code>ptr::read</code> requires the pointer to point to a valid value of <code>T</code>, because it returns a <code>T</code> (and if it didn't point to a valid <code>T</code>, that would violate the validity invariant). <code>ptr::write</code> on the other hand does not produce a <code>T</code> (it consumes a <code>T</code>), and performs no operations on the source, other than what is effectively a raw byte copy (in particular, it does not <code>drop</code> the source).  </p>
<blockquote>
<p>Thus UB is accessing uninitialized memory by reference, but not creation that one, am I correct? That's a little unintuitive for me then</p>
</blockquote>
<p>The TL;DR of the current position in the issue, is that there are cases where having a reference to invalid data is desirable. I don't remember any of the examples off the top of my head, though I believe one was to do with Atomics and objects with padding.  <br>
I'd point out the difference between "initialized" and "valid" is that uninitialized memory can be invalid for some types (notably, <code>MaybeUninit&lt;T&gt;</code>). It's undefined behaviour to produce an invalid value.</p>



<a name="220870800"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference%20in%20%60ptr%3A%3Awrite%60%20question/near/220870800" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference.20in.20.60ptr.3A.3Awrite.60.20question.html#220870800">(Dec 24 2020 at 13:47)</a>:</h4>
<p>Stdlib is special, in that it can abuse not-yet-exploited UB, since their code is tied to its specific compiler version, and so can positively know what is and isn't exploited UB. And having a Rust reference to uninitialized / invalid data is not exploited UB yet. But if a downstream user were to write that very same code, then it would technically be UB, since a future version of the compiler may choose to exploit that.</p>



<a name="220872287"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference%20in%20%60ptr%3A%3Awrite%60%20question/near/220872287" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Kitsu <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference.20in.20.60ptr.3A.3Awrite.60.20question.html#220872287">(Dec 24 2020 at 14:17)</a>:</h4>
<p>Thanks for the explanation, that cleared things out for me</p>



<a name="220872760"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference%20in%20%60ptr%3A%3Awrite%60%20question/near/220872760" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference.20in.20.60ptr.3A.3Awrite.60.20question.html#220872760">(Dec 24 2020 at 14:26)</a>:</h4>
<p>I am actually not sure why that code does that, because the intrinsic takes a raw pointer.</p>



<a name="220873377"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference%20in%20%60ptr%3A%3Awrite%60%20question/near/220873377" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference.20in.20.60ptr.3A.3Awrite.60.20question.html#220873377">(Dec 24 2020 at 14:38)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116122">simulacrum</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Reference.20in.20.60ptr.3A.3Awrite.60.20question/near/220872760">said</a>:</p>
<blockquote>
<p>I am actually not sure why that code does that, because the intrinsic takes a raw pointer.</p>
</blockquote>
<p>Probably to trip optimizations/miri when it would be UB. Though that might be incorrect, as you can alias raw pointers, and write to both aliased raw pointers. If it's taking a <code>&amp;mut T</code>, that would be an incorrect optimization when raw pointers are fully tracked.</p>



<a name="220925274"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference%20in%20%60ptr%3A%3Awrite%60%20question/near/220925274" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference.20in.20.60ptr.3A.3Awrite.60.20question.html#220925274">(Dec 25 2020 at 15:21)</a>:</h4>
<blockquote>
<p>Even if it did, &lt;<a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/77">https://github.com/rust-lang/unsafe-code-guidelines/issues/77</a>&gt; implies that references do not need to refer to valid data, and this is only a safety invariant (unrelated safe code may assume that references refer to valid data).</p>
</blockquote>
<p>It implies no such thing... that's juts my current proposal. The proposal hasn't even been accepted by the UCG yet, let alone RFC'd and t-lang approved.</p>



<a name="220925314"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference%20in%20%60ptr%3A%3Awrite%60%20question/near/220925314" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Reference.20in.20.60ptr.3A.3Awrite.60.20question.html#220925314">(Dec 25 2020 at 15:22)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116122">simulacrum</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Reference.20in.20.60ptr.3A.3Awrite.60.20question/near/220872760">said</a>:</p>
<blockquote>
<p>I am actually not sure why that code does that, because the intrinsic takes a raw pointer.</p>
</blockquote>
<p>my guess is, it's an oversight that we should fix.^^ but anyway my proposal is to <a href="https://github.com/rust-lang/rust/pull/80290">get rid of the intrinsic entirely</a>.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>